﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using RH.Common.Extensions;
using RH.Domain;
using RH.Web.ViewModels;
using RH.Web.Utility;
using AutoMapper;
using System.Web.Script.Serialization;
using System.Text;

namespace RH.Web.Controllers
{
    public class AjaxController : BaseController
    {
		private AppEntities _Context = new AppEntities();
        
		#region Constructors
		public AjaxController()
		{
		}

		public AjaxController(UserViewModel currentUser)
			: base(currentUser)
        {
        }
		#endregion Constructors

		#region Action Methods
        [HttpPost]
        public String AddProductToCompare(int productID)
        {
            Product product = _Context.Products.Include("ProductImages").FirstOrDefault(P => P.ID == productID);
            if (product != null)
            {
                ProductViewModel viewModel = new ProductViewModel();
                viewModel.ID = product.ID;
                viewModel.ProductUrl = product.ProductUrl;
                viewModel.Name = product.Name;
                if (product.ProductImages != null && product.ProductImages.Count > 0)
                {
                    viewModel.ProductImages = new List<ProductImageViewModel>();
                    ProductImageViewModel image = Mapper.Map<ProductImageViewModel>(product.ProductImages.ToList()[0]);
                    viewModel.ProductImages.Add(image);                    
                }
                List<ProductViewModel> storedList = SessionCache.ProductCompareList;
                if (storedList.Count < ConfigReader.MaxNoOfProductsCanBeCompare 
                    && storedList.FirstOrDefault(P => P.ID == productID) == null)
                {
                    storedList.Add(viewModel);
                    SessionCache.ProductCompareList = storedList;
                    return viewModel.ToJSON();
                }
            }
            return String.Empty;
        }

        /// <summary>
        /// Adds a Product to the Users Favourite List
        /// </summary>
        /// <param name="id"></param>
        /// <returns>
        /// Returns:
        /// >0 If everything is ok. Favorite entity ID would be the return value.
        /// -1 If the user is not logged in        
        /// -2 If the requested product was not found
        /// </returns>
        [HttpPost]
        //[Authorize(Roles="Admin,Company User,Company Admin,Site User")]
        public int AddToFavorite(int id)
        {
            if (LoggedInUser == null)
                return -1;

            Product product = _Context.Products.FirstOrDefault(P => P.ID == id);
            if (product == null)
                return -2;

            UserWishList favorite = new UserWishList();
            favorite.ProductID = product.ID;
            favorite.UserID = LoggedInUser.ID;
            favorite.UpdatedDate = DateTime.Now;

            _Context.AddToUserWishLists(favorite);
            _Context.SaveChanges();
            return favorite.ID;
        }
        /// <summary>
        /// Deletes a Product from the Session
        /// </summary>
        /// <param name="productID"></param>
        /// <returns></returns>
        [HttpPost]
        public int RemoveProductToCompare(int productID)
        {
            List<ProductViewModel> storedList = SessionCache.ProductCompareList;
            ProductViewModel product = storedList.FirstOrDefault(P => P.ID == productID);
            if (product != null)
            {
                storedList.Remove(product);
                SessionCache.ProductCompareList = storedList;
                return 1;
            }
            return 0;
        }
       
        /// <summary>
        /// Gets a JSON Collection of Locations by District
        /// </summary>
        /// <param name="countryID"></param>
        /// <returns></returns>
        public String GetLocationsByDistrict(int districtID = 0)
        {
            var query = from P in _Context.Locations
                        where P.DistrictID == districtID
                        orderby P.Name
                        select new
                        {
                            ID = P.ID,
                            Name = P.Name
                        };
            if (query == null || query.Count() == 0)
                return "{}";
            else
                return query.ToList().ToJSON();
        }

        /// <summary>
        /// Gets a JSON collection of Districts by Country
        /// </summary>
        /// <param name="stateID"></param>
        /// <returns></returns>
        [HttpPost]
        public String GetDistrictsByCountry(int countryID = 0)
        {
            var query = from P in _Context.Districts
                        where P.CountryID == countryID
                        orderby P.Name
                        select new
                        {
                            ID = P.ID,
                            Name = P.Name
                        };
            if (query == null || query.Count() == 0)
                return "{}";
            else
                return query.ToList().ToJSON();
        }

        /// <summary>
        /// Sends a job to a friend.
        /// </summary>
        /// <param name="productID"></param>
        /// <param name="userEmail"></param>
        /// <param name="friendEmail"></param>
        /// <returns>
        /// Returns different status based on situations. 
        /// Status > 0 -> Successfully Sent
        /// -1 -> Invalid Request
        /// -2 -> The Requested Job was not found, probably a hacking attempt
        /// -3 -> Unable to send the email, probably a SMTP server issue.
        /// </returns>
        [HttpPost]
        public int SendProductToFriend(int productID, String userEmail, String friendEmail)
        {
            if (productID <= 0 || userEmail.IsNullOrEmpty() || friendEmail.IsNullOrEmpty())
                return -1;

            Product product = _Context.Products.FirstOrDefault(P => P.ID == productID);
            if (product == null)
                return -2;
            else
            {
                StringBuilder template = new StringBuilder(WebUtil.ReadEmailTemplate(AppConstants.EmailTemplate.COMMON));
                StringBuilder message = new StringBuilder(10);
                message.Append("Hi,<br />");
                message.AppendFormat("Your friend send you a property information from {0}. Please check below:<br/><br/>", ConfigReader.SiteName);
                message.AppendFormat("<b>Name:</b><br/> {0}<br/><br/>", WebUtil.FormatData(product.Name));
                message.AppendFormat("<b>Property Description:</b><br/> {0}<br/><br/>", WebUtil.FormatData(product.Description));
                message.AppendFormat("For more details visit this <a href='{0}'>Property Details</a> page.", Url.ProductDetailsUrl(productID, product.ProductUrl, null, true));
                template.Replace(AppConstants.ETConstants.MESSAGE, message.ToString());
                template.Replace(AppConstants.ETConstants.DOMAIN, WebUtil.GetDomainAddress());
                String subject = String.Format("Received a job from {0}", ConfigReader.SiteName);
                if (WebUtil.SendMail(userEmail, friendEmail, ConfigReader.AdminEmail, String.Empty, subject, template.ToString()))
                    return 1;

                return -3;
            }
        }

        /// <summary>
        /// Saves a Search to for an user to reuse in later time from user dashboard.
        /// </summary>
        /// <param name="viewModel"></param>
        /// <returns>
        /// Returns 
        /// - 1 If the user is not logged in
        /// > 0 Saved search entity is saved and the returns the ID of the new entity. 
        /// </returns>
        //[Authorize(Roles="Admin,SiteUser,CompanyUser,CompanyAdmin")]
        public int SaveSearch(SavedSearchViewModel viewModel)
        {
            if (LoggedInUser != null)
            {
                SavedSearch entity = Mapper.Map<SavedSearchViewModel, SavedSearch>(viewModel);
                entity.SavedOn = DateTime.Now;
                entity.UserID = LoggedInUser.ID;
                _Context.AddToSavedSearches(entity);
                _Context.SaveChanges();
                return entity.ID;
            }
            return -1;
        }
        #endregion Action Methods

        #region Helper Methods
        //public int UpdatePayload()
        //{
        //    var products = _Context.Products.ToList();
        //    foreach (Product product in products)
        //    {
        //        System.Text.StringBuilder payload = new System.Text.StringBuilder(product.ZGLPayload);
        //        payload.Replace("<Product", "<ZGLPayload");
        //        payload.Replace("</Product>", "</ZGLPayload>");
        //        product.ZGLPayload = payload.ToString();                
        //    }
        //    return _Context.SaveChanges();            
        //}
        #endregion
    }
}
